package com.kust.smarthome.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kust.smarthome.web.model.*;
import com.kust.smarthome.web.service.*;
import com.kust.smarthome.web.utils.DistanceUtils;
import com.kust.smarthome.web.vo.WatchVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author iAuzre
 * @since 2021-07-06
 */
@RestController
@RequestMapping("/watch")
@Api(value = "智能表相关操作", tags = {"device-tag"})
public class WatchController {

    @Resource
    private IWatchService watchService;

    @Resource
    private IDeviceStateService deviceStateService;

    @Resource
    private INoticeService noticeService;

    @Resource
    private IUserService userService;

    @Resource
    private IRateService rateService;

    @Resource
    private IPersonDetailsService personDetailsService;

    @Resource
    private IPositionService positionService;

    @GetMapping("/getContent")
    @ApiOperation(value = "体温，心率，位置", notes = "用户查询家人的智能表的信息")
    public String getContent(Integer watchId){
        return watchService.getContent(watchId);
    }

    @GetMapping("")
    @ApiOperation(value = "智能表信息", notes = "用户查询对应用户的所有智能表信息")
    public List<Watch> list (Principal principal) {

        User user = userService.getByUsername(principal.getName());

        return watchService.getByUserId(user.getId());
    }


    @GetMapping("/getById")
    @ApiOperation(value = "getById", notes = "通过id获取对应设备")
    public Watch getById(Integer id) {
        return watchService.getById(id);
    }

    @Resource
    private DistanceUtils distanceUtils;

    /**
     * @param id watch_id
     * @param content watch_content 格式: T:36;R:70;J:128.01;W:33.91 分别代表体温;心率;经度;纬度
     */
    @GetMapping("/update")
    @Transactional
    @ApiOperation(value = "更新穿戴人身体信息", notes = "其中content字符串里面提供的信息为:体温、心率、经度、纬度")
    public void update(Integer id, String content) {

        Watch watch = watchService.getById(id);
        int userId = watch.getUserId();
        int personId = watch.getPersonId();

        String[] contents = content.split(";");
        int t = Integer.parseInt(contents[0].split(":")[1]);  //体温
        int rateNum = Integer.parseInt(contents[1].split(":")[1]);  //心率
        double lng = Double.parseDouble(contents[2].split(":")[1]);  //经度
        double lat = Double.parseDouble(contents[3].split(":")[1]);  //纬度

        //异常信息处理
        if (t >= 38) {
            warning(userId,id,"体温过高");
        } else if (t <= 36) {
            warning(userId,id,"体温过低");
        }

        Position position = positionService.getByUserId(userId);
        double longitude = position.getLongitude();
        double latitude = position.getLatitude();

        //获取watch定位与固定位置的距离
        double d = distanceUtils.getDistance(longitude,latitude,lng,lat);
        if (d > 5) {
            warning(userId,id,"超出活动范围");
        }

        //心率表信息更改
        Rate rate = rateService.getRate(userId, personId);
        String rateS = rate.getRate() + rateNum + ";";  //rateNum+";"放入原有的心率数据中去
        rate.setRate(rateS);
        rateService.updateById(rate);

        //详细信息表修改
        PersonDetails personDetails = personDetailsService.getPersonDetails(userId, personId);
        personDetails.setRateNow(rateNum);
        personDetailsService.updateById(personDetails);

        //设备状态表
        DeviceState deviceState = new DeviceState()
                .setDeviceId(id)
                .setTypeId(8)
                .setIsUpdate(0);
        //更改状态通知
        QueryWrapper<DeviceState> queryD = new QueryWrapper<>();
        queryD.eq("device_id",id);
        queryD.eq("type_id",8);
        deviceStateService.update(deviceState,queryD);


    }

    public void warning(Integer userId, Integer id, String content) {

        Notice notice = new Notice()
                .setUserId(userId)
                .setTypeId(8)
                .setDeviceId(id)
                .setContent(content)
                .setCreated(LocalDateTime.now())
                .setState(0);

        noticeService.save(notice);
    }

    @GetMapping("/add")
    @Transactional
    @ApiOperation(value = "添加智能穿戴设备", notes = "用户提供智能穿戴设备id,穿戴者id进行添加操作")
    public void add(Principal principal, WatchVo watchVo) {

        User user = userService.getByUsername(principal.getName());

        Watch watch = new Watch()
                .setId(watchVo.getId())
                .setUserId(user.getId())
                .setPersonId(watchVo.getPersonId())
                .setContent("")
                .setCreated(LocalDateTime.now());

        watchService.insert(watch);

        DeviceState deviceState = new DeviceState()
                .setDeviceId(watchVo.getId())
                .setTypeId(8)
                .setIsUpdate(0);
        deviceStateService.insert(deviceState);

        Rate rate = new Rate()
                .setUserId(user.getId())
                .setPersonId(watchVo.getPersonId())
                .setRate("")
                .setCreated(LocalDateTime.now());
        rateService.insert(rate);
    }

    @GetMapping("/deleteById")
    @Transactional
    @ApiOperation(value = "删除智能手环", notes = "通过用户提供的id删除对应的智能手环")
    public boolean deleteById(Principal principal, Integer id) {
        User user = userService.getByUsername(principal.getName());
        Watch watch = watchService.getById(id);
        watch.setUserId(-1);

        //清除 personDetails 中的心率信息
        PersonDetails personDetails = personDetailsService.getById(watch.getPersonId());
        personDetails.setRateNow(null);
        personDetailsService.updateById(personDetails);

        //清除 rate 中的心率信息
        Rate rate = rateService.getRate(user.getId(), watch.getPersonId());
        rate.setRate(null);
        rateService.updateById(rate);

        QueryWrapper<DeviceState> query = new QueryWrapper<>();
        query.eq("device_id", id)
                .eq("type_id", 8);
        deviceStateService.remove(query);

        return watchService.updateById(watch);
    }


}
